/**
 ****************************************************************************************************
 * @file        lcd.c
 * @author      姝ｇ偣鍘熷瓙鍥㈤槦(ALIENTEK)
 * @version     V1.1
 * @date        2023-05-29
 * @brief       2.8瀵�/3.5瀵�/4.3瀵�/7瀵� TFTLCD(MCU灞�) 椹卞姩浠ｇ爜
 *              鏀寔椹卞姩IC鍨嬪彿鍖呮嫭:ILI9341/NT35310/NT35510/SSD1963/ST7789/ST7796/ILI9806绛�
 *
 * @license     Copyright (c) 2020-2032, 骞垮窞甯傛槦缈肩數瀛愮鎶�鏈夐檺鍏徃
 ****************************************************************************************************
 * @attention
 *
 * 瀹為獙骞冲彴:姝ｇ偣鍘熷瓙 鎺㈢储鑰� F407寮�鍙戞澘
 * 鍦ㄧ嚎瑙嗛:www.yuanzige.com
 * 鎶�鏈鍧�:www.openedv.com
 * 鍏徃缃戝潃:www.alientek.com
 * 璐拱鍦板潃:openedv.taobao.com
 *
 * 淇敼璇存槑
 * V1.0 20211016
 * 绗竴娆″彂甯�
 * V1.1 20230529
 * 1锛屾柊澧炲ST7796鍜孖LI9806 IC鏀寔
 * 2锛岀畝鍖栭儴鍒嗕唬鐮侊紝閬垮厤闀垮垽瀹�
 ****************************************************************************************************
 */

#include "stdlib.h"
#include "lcd.h"
#include "lcdfont.h"
#include "delay.h"
#include "string.h"



/* lcd_ex.c瀛樻斁鍚勪釜LCD椹卞姩IC鐨勫瘎瀛樺櫒鍒濆鍖栭儴鍒嗕唬鐮�,浠ョ畝鍖杔cd.c,璇�.c鏂囦欢
 * 涓嶇洿鎺ュ姞鍏ュ埌宸ョ▼閲岄潰,鍙湁lcd.c浼氱敤鍒�,鎵�浠ラ�氳繃include鐨勫舰寮忔坊鍔�.(涓嶈鍦�
 * 鍏朵粬鏂囦欢鍐嶅寘鍚.c鏂囦欢!!鍚﹀垯浼氭姤閿�!)
 */
#include "lcd_ex.c"


SRAM_HandleTypeDef g_sram_handle;   /* SRAM鍙ユ焺(鐢ㄤ簬鎺у埗LCD) */

/* LCD鐨勭敾绗旈鑹插拰鑳屾櫙鑹� */
uint32_t g_point_color = 0xF800;    /* 鐢荤瑪棰滆壊 */
uint32_t g_back_color  = 0xFFFF;    /* 鑳屾櫙鑹� */

/* 绠＄悊LCD閲嶈鍙傛暟 */
_lcd_dev lcddev;

/**
 * @brief       LCD鍐欐暟鎹�
 * @param       data: 瑕佸啓鍏ョ殑鏁版嵁
 * @retval      鏃�
 */
void lcd_wr_data(volatile uint16_t data)
{
    data = data;            /* 浣跨敤-O2浼樺寲鐨勬椂鍊�,蹇呴』鎻掑叆鐨勫欢鏃� */
    LCD->LCD_RAM = data;
}

/**
 * @brief       LCD鍐欏瘎瀛樺櫒缂栧彿/鍦板潃鍑芥暟
 * @param       regno: 瀵勫瓨鍣ㄧ紪鍙�/鍦板潃
 * @retval      鏃�
 */
void lcd_wr_regno(volatile uint16_t regno)
{
    regno = regno;          /* 浣跨敤-O2浼樺寲鐨勬椂鍊�,蹇呴』鎻掑叆鐨勫欢鏃� */
    LCD->LCD_REG = regno;   /* 鍐欏叆瑕佸啓鐨勫瘎瀛樺櫒搴忓彿 */
}

/**
 * @brief       LCD鍐欏瘎瀛樺櫒
 * @param       regno:瀵勫瓨鍣ㄧ紪鍙�/鍦板潃
 * @param       data:瑕佸啓鍏ョ殑鏁版嵁
 * @retval      鏃�
 */
void lcd_write_reg(uint16_t regno, uint16_t data)
{
    LCD->LCD_REG = regno;   /* 鍐欏叆瑕佸啓鐨勫瘎瀛樺櫒搴忓彿 */
    LCD->LCD_RAM = data;    /* 鍐欏叆鏁版嵁 */
}

/**
 * @brief       LCD寤舵椂鍑芥暟,浠呯敤浜庨儴鍒嗗湪mdk -O1鏃堕棿浼樺寲鏃堕渶瑕佽缃殑鍦版柟
 * @param       t:寤舵椂鐨勬暟鍊�
 * @retval      鏃�
 */
static void lcd_opt_delay(uint32_t i)
{
    while (i--); /* 浣跨敤AC6鏃剁┖寰幆鍙兘琚紭鍖�,鍙娇鐢╳hile(1) __asm volatile(""); */
}

/**
 * @brief       LCD璇绘暟鎹�
 * @param       鏃�
 * @retval      璇诲彇鍒扮殑鏁版嵁
 */
static uint16_t lcd_rd_data(void)
{
    volatile uint16_t ram;  /* 闃叉琚紭鍖� */
    lcd_opt_delay(2);
    ram = LCD->LCD_RAM;
    return ram;
}

/**
 * @brief       鍑嗗鍐橤RAM
 * @param       鏃�
 * @retval      鏃�
 */
void lcd_write_ram_prepare(void)
{
    LCD->LCD_REG = lcddev.wramcmd;
}

/**
 * @brief       璇诲彇涓煇鐐圭殑棰滆壊鍊�
 * @param       x,y:鍧愭爣
 * @retval      姝ょ偣鐨勯鑹�(32浣嶉鑹�,鏂逛究鍏煎LTDC)
 */
uint32_t lcd_read_point(uint16_t x, uint16_t y)
{
    uint16_t r = 0, g = 0, b = 0;

    if (x >= lcddev.width || y >= lcddev.height)
    {
        return 0;   /* 瓒呰繃浜嗚寖鍥�,鐩存帴杩斿洖 */
    }

    lcd_set_cursor(x, y);       /* 璁剧疆鍧愭爣 */

    if (lcddev.id == 0x5510)
    {
        lcd_wr_regno(0x2E00);   /* 5510 鍙戦�佽GRAM鎸囦护 */
    }
    else
    {
        lcd_wr_regno(0x2E);     /* 9341/5310/1963/7789/7796/9806 绛夊彂閫佽GRAM鎸囦护 */
    }


    r = lcd_rd_data();          /* 鍋囪(dummy read) */

    if (lcddev.id == 0x1963)
    {
        return r;   /* 1963鐩存帴璇诲氨鍙互 */
    }

    r = lcd_rd_data();          /* 瀹為檯鍧愭爣棰滆壊 */

    if (lcddev.id == 0x7796)    /* 7796 涓�娆¤鍙栦竴涓儚绱犲�� */
    {
        return r;
    }

    /* 9341/5310/5510/7789/9806瑕佸垎2娆¤鍑� */
    b = lcd_rd_data();
    g = r & 0xFF;               /* 瀵逛簬9341/5310/5510/7789/9806,绗竴娆¤鍙栫殑鏄疪G鐨勫��,R鍦ㄥ墠,G鍦ㄥ悗,鍚勫崰8浣� */
    g <<= 8;

    return (((r >> 11) << 11) | ((g >> 10) << 5) | (b >> 11));  /* ILI9341/NT35310/NT35510/ST7789/ILI9806闇�瑕佸叕寮忚浆鎹竴涓� */
}

/**
 * @brief       LCD寮�鍚樉绀�
 * @param       鏃�
 * @retval      鏃�
 */
void lcd_display_on(void)
{
    if (lcddev.id == 0x5510)
    {
        lcd_wr_regno(0x2900);   /* 寮�鍚樉绀� */
    }
    else                        /* 9341/5310/1963/7789/7796/9806 绛夊彂閫佸紑鍚樉绀烘寚浠� */
    {
        lcd_wr_regno(0x29);     /* 寮�鍚樉绀� */
    }
}

/**
 * @brief       LCD鍏抽棴鏄剧ず
 * @param       鏃�
 * @retval      鏃�
 */
void lcd_display_off(void)
{
    if (lcddev.id == 0x5510)
    {
        lcd_wr_regno(0x2800);   /* 鍏抽棴鏄剧ず */
    }
    else                        /* 9341/5310/1963/7789/7796/9806 绛夊彂閫佸叧闂樉绀烘寚浠� */
    {
        lcd_wr_regno(0x28);     /* 鍏抽棴鏄剧ず */
    }
}

/**
 * @brief       璁剧疆鍏夋爣浣嶇疆(瀵筊GB灞忔棤鏁�)
 * @param       x,y: 鍧愭爣
 * @retval      鏃�
 */
void lcd_set_cursor(uint16_t x, uint16_t y)
{
    if (lcddev.id == 0x1963)
    {
        if (lcddev.dir == 0)    /* 绔栧睆妯″紡, x鍧愭爣闇�瑕佸彉鎹� */
        {
            x = lcddev.width - 1 - x;
            lcd_wr_regno(lcddev.setxcmd);
            lcd_wr_data(0);
            lcd_wr_data(0);
            lcd_wr_data(x >> 8);
            lcd_wr_data(x & 0xFF);
        }
        else                    /* 妯睆妯″紡 */
        {
            lcd_wr_regno(lcddev.setxcmd);
            lcd_wr_data(x >> 8);
            lcd_wr_data(x & 0xFF);
            lcd_wr_data((lcddev.width - 1) >> 8);
            lcd_wr_data((lcddev.width - 1) & 0xFF);
        }

        lcd_wr_regno(lcddev.setycmd);
        lcd_wr_data(y >> 8);
        lcd_wr_data(y & 0xFF);
        lcd_wr_data((lcddev.height - 1) >> 8);
        lcd_wr_data((lcddev.height - 1) & 0xFF);

    }
    else if (lcddev.id == 0x5510)
    {
        lcd_wr_regno(lcddev.setxcmd);
        lcd_wr_data(x >> 8);
        lcd_wr_regno(lcddev.setxcmd + 1);
        lcd_wr_data(x & 0xFF);
        lcd_wr_regno(lcddev.setycmd);
        lcd_wr_data(y >> 8);
        lcd_wr_regno(lcddev.setycmd + 1);
        lcd_wr_data(y & 0xFF);
    }
    else    /* 9341/5310/7789/7796/9806 绛� 璁剧疆鍧愭爣 */
    {
        lcd_wr_regno(lcddev.setxcmd);
        lcd_wr_data(x >> 8);
        lcd_wr_data(x & 0xFF);
        lcd_wr_regno(lcddev.setycmd);
        lcd_wr_data(y >> 8);
        lcd_wr_data(y & 0xFF);
    }
}

/**
 * @brief       璁剧疆LCD鐨勮嚜鍔ㄦ壂鎻忔柟鍚�(瀵筊GB灞忔棤鏁�)
 *   @note
 *              9341/5310/5510/1963/7789/7796/9806绛塈C宸茬粡瀹為檯娴嬭瘯
 *              娉ㄦ剰:鍏朵粬鍑芥暟鍙兘浼氬彈鍒版鍑芥暟璁剧疆鐨勫奖鍝�(灏ゅ叾鏄�9341),
 *              鎵�浠�,涓�鑸缃负L2R_U2D鍗冲彲,濡傛灉璁剧疆涓哄叾浠栨壂鎻忔柟寮�,鍙兘瀵艰嚧鏄剧ず涓嶆甯�.
 *
 * @param       dir:0~7,浠ｈ〃8涓柟鍚�(鍏蜂綋瀹氫箟瑙乴cd.h)
 * @retval      鏃�
 */
void lcd_scan_dir(uint8_t dir)
{
    uint16_t regval = 0;
    uint16_t dirreg = 0;
    uint16_t temp;

    /* 妯睆鏃讹紝瀵�1963涓嶆敼鍙樻壂鎻忔柟鍚戯紒绔栧睆鏃�1963鏀瑰彉鏂瑰悜(杩欓噷浠呯敤浜�1963鐨勭壒娈婂鐞�,瀵瑰叾浠栭┍鍔↖C鏃犳晥) */
    if ((lcddev.dir == 1 && lcddev.id != 0x1963) || (lcddev.dir == 0 && lcddev.id == 0x1963))
    {
        switch (dir)   /* 鏂瑰悜杞崲 */
        {
            case 0:
                dir = 6;
                break;

            case 1:
                dir = 7;
                break;

            case 2:
                dir = 4;
                break;

            case 3:
                dir = 5;
                break;

            case 4:
                dir = 1;
                break;

            case 5:
                dir = 0;
                break;

            case 6:
                dir = 3;
                break;

            case 7:
                dir = 2;
                break;
        }
    }


    /* 鏍规嵁鎵弿鏂瑰紡 璁剧疆 0x36/0x3600 瀵勫瓨鍣� bit 5,6,7 浣嶇殑鍊� */
    switch (dir)
    {
        case L2R_U2D:   /* 浠庡乏鍒板彸,浠庝笂鍒颁笅 */
            regval |= (0 << 7) | (0 << 6) | (0 << 5);
            break;

        case L2R_D2U:   /* 浠庡乏鍒板彸,浠庝笅鍒颁笂 */
            regval |= (1 << 7) | (0 << 6) | (0 << 5);
            break;

        case R2L_U2D:   /* 浠庡彸鍒板乏,浠庝笂鍒颁笅 */
            regval |= (0 << 7) | (1 << 6) | (0 << 5);
            break;

        case R2L_D2U:   /* 浠庡彸鍒板乏,浠庝笅鍒颁笂 */
            regval |= (1 << 7) | (1 << 6) | (0 << 5);
            break;

        case U2D_L2R:   /* 浠庝笂鍒颁笅,浠庡乏鍒板彸 */
            regval |= (0 << 7) | (0 << 6) | (1 << 5);
            break;

        case U2D_R2L:   /* 浠庝笂鍒颁笅,浠庡彸鍒板乏 */
            regval |= (0 << 7) | (1 << 6) | (1 << 5);
            break;

        case D2U_L2R:   /* 浠庝笅鍒颁笂,浠庡乏鍒板彸 */
            regval |= (1 << 7) | (0 << 6) | (1 << 5);
            break;

        case D2U_R2L:   /* 浠庝笅鍒颁笂,浠庡彸鍒板乏 */
            regval |= (1 << 7) | (1 << 6) | (1 << 5);
            break;
    }

    dirreg = 0x36;  /* 瀵圭粷澶ч儴鍒嗛┍鍔↖C, 鐢�0x36瀵勫瓨鍣ㄦ帶鍒� */

    if (lcddev.id == 0x5510)
    {
        dirreg = 0x3600;    /* 瀵逛簬5510, 鍜屽叾浠栭┍鍔╥c鐨勫瘎瀛樺櫒鏈夊樊寮� */
    }

     /* 9341 & 7789 & 7796 瑕佽缃瓸GR浣� */
    if (lcddev.id == 0x9341 || lcddev.id == 0x7789 || lcddev.id == 0x7796)
    {
        regval |= 0x08;
    }

    lcd_write_reg(dirreg, regval);

    if (lcddev.id != 0x1963)                    /* 1963涓嶅仛鍧愭爣澶勭悊 */
    {
        if (regval & 0x20)
        {
            if (lcddev.width < lcddev.height)   /* 浜ゆ崲X,Y */
            {
                temp = lcddev.width;
                lcddev.width = lcddev.height;
                lcddev.height = temp;
            }
        }
        else
        {
            if (lcddev.width > lcddev.height)   /* 浜ゆ崲X,Y */
            {
                temp = lcddev.width;
                lcddev.width = lcddev.height;
                lcddev.height = temp;
            }
        }
    }

    /* 璁剧疆鏄剧ず鍖哄煙(寮�绐�)澶у皬 */
    if (lcddev.id == 0x5510)
    {
        lcd_wr_regno(lcddev.setxcmd);
        lcd_wr_data(0);
        lcd_wr_regno(lcddev.setxcmd + 1);
        lcd_wr_data(0);
        lcd_wr_regno(lcddev.setxcmd + 2);
        lcd_wr_data((lcddev.width - 1) >> 8);
        lcd_wr_regno(lcddev.setxcmd + 3);
        lcd_wr_data((lcddev.width - 1) & 0xFF);
        lcd_wr_regno(lcddev.setycmd);
        lcd_wr_data(0);
        lcd_wr_regno(lcddev.setycmd + 1);
        lcd_wr_data(0);
        lcd_wr_regno(lcddev.setycmd + 2);
        lcd_wr_data((lcddev.height - 1) >> 8);
        lcd_wr_regno(lcddev.setycmd + 3);
        lcd_wr_data((lcddev.height - 1) & 0xFF);
    }
    else
    {
        lcd_wr_regno(lcddev.setxcmd);
        lcd_wr_data(0);
        lcd_wr_data(0);
        lcd_wr_data((lcddev.width - 1) >> 8);
        lcd_wr_data((lcddev.width - 1) & 0xFF);
        lcd_wr_regno(lcddev.setycmd);
        lcd_wr_data(0);
        lcd_wr_data(0);
        lcd_wr_data((lcddev.height - 1) >> 8);
        lcd_wr_data((lcddev.height - 1) & 0xFF);
    }
}

/**
 * @brief       鐢荤偣
 * @param       x,y: 鍧愭爣
 * @param       color: 鐐圭殑棰滆壊(32浣嶉鑹�,鏂逛究鍏煎LTDC)
 * @retval      鏃�
 */
void lcd_draw_point(uint16_t x, uint16_t y, uint32_t color)
{
    lcd_set_cursor(x, y);       /* 璁剧疆鍏夋爣浣嶇疆 */
    lcd_write_ram_prepare();    /* 寮�濮嬪啓鍏RAM */
    LCD->LCD_RAM = color;
}

/**
 * @brief       SSD1963鑳屽厜浜害璁剧疆鍑芥暟
 * @param       pwm: 鑳屽厜绛夌骇,0~100.瓒婂ぇ瓒婁寒.
 * @retval      鏃�
 */
void lcd_ssd_backlight_set(uint8_t pwm)
{
    lcd_wr_regno(0xBE);         /* 閰嶇疆PWM杈撳嚭 */
    lcd_wr_data(0x05);          /* 1璁剧疆PWM棰戠巼 */
    lcd_wr_data(pwm * 2.55);    /* 2璁剧疆PWM鍗犵┖姣� */
    lcd_wr_data(0x01);          /* 3璁剧疆C */
    lcd_wr_data(0xFF);          /* 4璁剧疆D */
    lcd_wr_data(0x00);          /* 5璁剧疆E */
    lcd_wr_data(0x00);          /* 6璁剧疆F */
}

/**
 * @brief       璁剧疆LCD鏄剧ず鏂瑰悜
 * @param       dir:0,绔栧睆; 1,妯睆
 * @retval      鏃�
 */
void lcd_display_dir(uint8_t dir)
{
    lcddev.dir = dir;   /* 绔栧睆/妯睆 */

    if (dir == 0)       /* 绔栧睆 */
    {
        lcddev.width = 240;
        lcddev.height = 320;

        if (lcddev.id == 0x5510)
        {
            lcddev.wramcmd = 0x2C00;
            lcddev.setxcmd = 0x2A00;
            lcddev.setycmd = 0x2B00;
            lcddev.width = 480;
            lcddev.height = 800;
        }
        else if (lcddev.id == 0x1963)
        {
            lcddev.wramcmd = 0x2C;  /* 璁剧疆鍐欏叆GRAM鐨勬寚浠� */
            lcddev.setxcmd = 0x2B;  /* 璁剧疆鍐橷鍧愭爣鎸囦护 */
            lcddev.setycmd = 0x2A;  /* 璁剧疆鍐橸鍧愭爣鎸囦护 */
            lcddev.width = 480;     /* 璁剧疆瀹藉害480 */
            lcddev.height = 800;    /* 璁剧疆楂樺害800 */
        }
        else   /* 鍏朵粬IC, 鍖呮嫭: 9341/5310/7789/7796/9806绛塈C */
        {
            lcddev.wramcmd = 0x2C;
            lcddev.setxcmd = 0x2A;
            lcddev.setycmd = 0x2B;
        }

        if (lcddev.id == 0x5310 || lcddev.id == 0x7796)     /* 濡傛灉鏄�5310/7796 鍒欒〃绀烘槸 320*480鍒嗚鲸鐜� */
        {
            lcddev.width = 320;
            lcddev.height = 480;
        }

        if (lcddev.id == 0X9806)    /* 濡傛灉鏄�9806 鍒欒〃绀烘槸 480*800 鍒嗚鲸鐜� */
        {
            lcddev.width = 480;
            lcddev.height = 800;
        }
    }
    else        /* 妯睆 */
    {
        lcddev.width = 320;         /* 榛樿瀹藉害 */
        lcddev.height = 240;        /* 榛樿楂樺害 */

        if (lcddev.id == 0x5510)
        {
            lcddev.wramcmd = 0x2C00;
            lcddev.setxcmd = 0x2A00;
            lcddev.setycmd = 0x2B00;
            lcddev.width = 800;
            lcddev.height = 480;
        }
        else if (lcddev.id == 0x1963 || lcddev.id == 0x9806)
        {
            lcddev.wramcmd = 0x2C;  /* 璁剧疆鍐欏叆GRAM鐨勬寚浠� */
            lcddev.setxcmd = 0x2A;  /* 璁剧疆鍐橷鍧愭爣鎸囦护 */
            lcddev.setycmd = 0x2B;  /* 璁剧疆鍐橸鍧愭爣鎸囦护 */
            lcddev.width = 800;     /* 璁剧疆瀹藉害800 */
            lcddev.height = 480;    /* 璁剧疆楂樺害480 */
        }
        else   /* 鍏朵粬IC, 鍖呮嫭:9341/5310/7789/7796绛塈C */
        {
            lcddev.wramcmd = 0x2C;
            lcddev.setxcmd = 0x2A;
            lcddev.setycmd = 0x2B;
        }

        if (lcddev.id == 0x5310 || lcddev.id == 0x7796)     /* 濡傛灉鏄�5310/7796 鍒欒〃绀烘槸 320*480鍒嗚鲸鐜� */
        {
            lcddev.width = 480;
            lcddev.height = 320;
        }
    }

    lcd_scan_dir(DFT_SCAN_DIR);     /* 榛樿鎵弿鏂瑰悜 */
}

/**
 * @brief       璁剧疆绐楀彛(瀵筊GB灞忔棤鏁�), 骞惰嚜鍔ㄨ缃敾鐐瑰潗鏍囧埌绐楀彛宸︿笂瑙�(sx,sy).
 * @param       sx,sy:绐楀彛璧峰鍧愭爣(宸︿笂瑙�)
 * @param       width,height:绐楀彛瀹藉害鍜岄珮搴�,蹇呴』澶т簬0!!
 *   @note      绐椾綋澶у皬:width*height.
 *
 * @retval      鏃�
 */
void lcd_set_window(uint16_t sx, uint16_t sy, uint16_t width, uint16_t height)
{
    uint16_t twidth, theight;
    twidth = sx + width - 1;
    theight = sy + height - 1;

   
   if (lcddev.id == 0x1963 && lcddev.dir != 1)     /* 1963绔栧睆鐗规畩澶勭悊 */
    {
        sx = lcddev.width - width - sx;
        height = sy + height - 1;
        lcd_wr_regno(lcddev.setxcmd);
        lcd_wr_data(sx >> 8);
        lcd_wr_data(sx & 0xFF);
        lcd_wr_data((sx + width - 1) >> 8);
        lcd_wr_data((sx + width - 1) & 0xFF);
        lcd_wr_regno(lcddev.setycmd);
        lcd_wr_data(sy >> 8);
        lcd_wr_data(sy & 0xFF);
        lcd_wr_data(height >> 8);
        lcd_wr_data(height & 0xFF);
    }
    else if (lcddev.id == 0x5510)
    {
        lcd_wr_regno(lcddev.setxcmd);
        lcd_wr_data(sx >> 8);
        lcd_wr_regno(lcddev.setxcmd + 1);
        lcd_wr_data(sx & 0xFF);
        lcd_wr_regno(lcddev.setxcmd + 2);
        lcd_wr_data(twidth >> 8);
        lcd_wr_regno(lcddev.setxcmd + 3);
        lcd_wr_data(twidth & 0xFF);
        lcd_wr_regno(lcddev.setycmd);
        lcd_wr_data(sy >> 8);
        lcd_wr_regno(lcddev.setycmd + 1);
        lcd_wr_data(sy & 0xFF);
        lcd_wr_regno(lcddev.setycmd + 2);
        lcd_wr_data(theight >> 8);
        lcd_wr_regno(lcddev.setycmd + 3);
        lcd_wr_data(theight & 0xFF);
    }
    else    /* 9341/5310/7789/1963/7796/9806妯睆 绛� 璁剧疆绐楀彛 */
    {
        lcd_wr_regno(lcddev.setxcmd);
        lcd_wr_data(sx >> 8);
        lcd_wr_data(sx & 0xFF);
        lcd_wr_data(twidth >> 8);
        lcd_wr_data(twidth & 0xFF);
        lcd_wr_regno(lcddev.setycmd);
        lcd_wr_data(sy >> 8);
        lcd_wr_data(sy & 0xFF);
        lcd_wr_data(theight >> 8);
        lcd_wr_data(theight & 0xFF);
    }
}



/**
 * @brief       鍒濆鍖朙CD
 *   @note      璇ュ垵濮嬪寲鍑芥暟鍙互鍒濆鍖栧悇绉嶅瀷鍙风殑LCD(璇﹁鏈�.c鏂囦欢鏈�鍓嶉潰鐨勬弿杩�)
 *
 * @param       鏃�
 * @retval      鏃�
 */
void lcd_init(void)
{

    FSMC_NORSRAM_TimingTypeDef fsmc_write_handle;



    /* 灏濊瘯9341 ID鐨勮鍙� */
    lcd_wr_regno(0xD3);
    lcddev.id = lcd_rd_data();  /* dummy read */
    lcddev.id = lcd_rd_data();  /* 璇诲埌0x00 */
    lcddev.id = lcd_rd_data();  /* 璇诲彇93 */
    lcddev.id <<= 8;
    lcddev.id |= lcd_rd_data(); /* 璇诲彇41 */

    if (lcddev.id != 0x9341)    /* 涓嶆槸 9341 , 灏濊瘯鐪嬬湅鏄笉鏄� ST7789 */
    {
        lcd_wr_regno(0x04);
        lcddev.id = lcd_rd_data();      /* dummy read */
        lcddev.id = lcd_rd_data();      /* 璇诲埌0x85 */
        lcddev.id = lcd_rd_data();      /* 璇诲彇0x85 */
        lcddev.id <<= 8;
        lcddev.id |= lcd_rd_data();     /* 璇诲彇0x52 */
        
        if (lcddev.id == 0x8552)        /* 灏�8552鐨処D杞崲鎴�7789 */
        {
            lcddev.id = 0x7789;
        }

        if (lcddev.id != 0x7789)        /* 涔熶笉鏄疭T7789, 灏濊瘯鏄笉鏄� NT35310 */
        {
            lcd_wr_regno(0xD4);
            lcddev.id = lcd_rd_data();  /* dummy read */
            lcddev.id = lcd_rd_data();  /* 璇诲洖0x01 */
            lcddev.id = lcd_rd_data();  /* 璇诲洖0x53 */
            lcddev.id <<= 8;
            lcddev.id |= lcd_rd_data(); /* 杩欓噷璇诲洖0x10 */

            if (lcddev.id != 0x5310)    /* 涔熶笉鏄疦T35310,灏濊瘯鐪嬬湅鏄笉鏄疭T7796 */
            {
                lcd_wr_regno(0XD3);
                lcddev.id = lcd_rd_data();  /* dummy read */
                lcddev.id = lcd_rd_data();  /* 璇诲埌0X00 */
                lcddev.id = lcd_rd_data();  /* 璇诲彇0X77 */
                lcddev.id <<= 8;
                lcddev.id |= lcd_rd_data(); /* 璇诲彇0X96 */

                if (lcddev.id != 0x7796)    /* 涔熶笉鏄疭T7796,灏濊瘯鐪嬬湅鏄笉鏄疦T35510 */
                {
                    /* 鍙戦�佸瘑閽ワ紙鍘傚鎻愪緵锛� */
                    lcd_write_reg(0xF000, 0x0055);
                    lcd_write_reg(0xF001, 0x00AA);
                    lcd_write_reg(0xF002, 0x0052);
                    lcd_write_reg(0xF003, 0x0008);
                    lcd_write_reg(0xF004, 0x0001);

                    lcd_wr_regno(0xC500);       /* 璇诲彇ID浣庡叓浣� */
                    lcddev.id = lcd_rd_data();  /* 璇诲洖0x80 */
                    lcddev.id <<= 8;

                    lcd_wr_regno(0xC501);       /* 璇诲彇ID楂樺叓浣� */
                    lcddev.id |= lcd_rd_data(); /* 璇诲洖0x00 */

                    delay_ms(5);                /* 绛夊緟5ms, 鍥犱负0XC501鎸囦护瀵�1963鏉ヨ灏辨槸杞欢澶嶄綅鎸囦护, 绛夊緟5ms璁�1963澶嶄綅瀹屾垚鍐嶆搷浣� */

                    if (lcddev.id != 0x5510)    /* 涔熶笉鏄疦T5510,灏濊瘯鐪嬬湅鏄笉鏄疘LI9806 */
                    {
                        lcd_wr_regno(0XD3);
                        lcddev.id = lcd_rd_data();  /* dummy read */
                        lcddev.id = lcd_rd_data();  /* 璇诲洖0X00 */
                        lcddev.id = lcd_rd_data();  /* 璇诲洖0X98 */
                        lcddev.id <<= 8;
                        lcddev.id |= lcd_rd_data(); /* 璇诲洖0X06 */

                        if (lcddev.id != 0x9806)    /* 涔熶笉鏄疘LI9806,灏濊瘯鐪嬬湅鏄笉鏄疭SD1963 */
                        {
                            lcd_wr_regno(0xA1);
                            lcddev.id = lcd_rd_data();
                            lcddev.id = lcd_rd_data();  /* 璇诲洖0x57 */
                            lcddev.id <<= 8;
                            lcddev.id |= lcd_rd_data(); /* 璇诲洖0x61 */

                            if (lcddev.id == 0x5761) lcddev.id = 0x1963; /* SSD1963璇诲洖鐨処D鏄�5761H,涓烘柟渚垮尯鍒�,鎴戜滑寮哄埗璁剧疆涓�1963 */
                        }
                    }
                }
            }
        }
    }

    /* 鐗瑰埆娉ㄦ剰, 濡傛灉鍦╩ain鍑芥暟閲岄潰灞忚斀涓插彛1鍒濆鍖�, 鍒欎細鍗℃鍦╬rintf
     * 閲岄潰(鍗℃鍦╢_putc鍑芥暟), 鎵�浠�, 蹇呴』鍒濆鍖栦覆鍙�1, 鎴栬�呭睆钄芥帀涓嬮潰
     * 杩欒 printf 璇彞 !!!!!!!
     */
    //printf("LCD ID:%x\r\n", lcddev.id); /* 鎵撳嵃LCD ID */

    if (lcddev.id == 0x7789)
    {
        lcd_ex_st7789_reginit();    /* 鎵цST7789鍒濆鍖� */
    }
    else if (lcddev.id == 0x9341)
    {
        lcd_ex_ili9341_reginit();   /* 鎵цILI9341鍒濆鍖� */
    }
    else if (lcddev.id == 0x5310)
    {
        lcd_ex_nt35310_reginit();   /* 鎵цNT35310鍒濆鍖� */
    }
//    else if (lcddev.id == 0x7796)
//    {
//        lcd_ex_st7796_reginit();    /* 鎵цST7796鍒濆鍖� */
//    }
    else if (lcddev.id == 0x5510)
    {
        lcd_ex_nt35510_reginit();   /* 鎵цNT35510鍒濆鍖� */
    }
//    else if (lcddev.id == 0x9806)
//    {
//        lcd_ex_ili9806_reginit();   /* 鎵цILI9806鍒濆鍖� */
//    }
    else if (lcddev.id == 0x1963)
    {
        lcd_ex_ssd1963_reginit();   /* 鎵цSSD1963鍒濆鍖� */
        lcd_ssd_backlight_set(100); /* 鑳屽厜璁剧疆涓烘渶浜� */
    }

    /* 鐢变簬涓嶅悓灞忓箷鐨勫啓鏃跺簭涓嶅悓锛岃繖閲岀殑鏃跺簭鍙互鏍规嵁鑷繁鐨勫睆骞曡繘琛屼慨鏀�
      锛堣嫢鎻掍笂闀挎帓绾垮鏃跺簭涔熶細鏈夊奖鍝嶏紝闇�瑕佽嚜宸辨牴鎹儏鍐典慨鏀癸級 */
    /* 鍒濆鍖栧畬鎴愪互鍚�,鎻愰�� */
    if (lcddev.id == 0x7789)
    {
        /* 閲嶆柊閰嶇疆鍐欐椂搴忔帶鍒跺瘎瀛樺櫒鐨勬椂搴� */
        fsmc_write_handle.AddressSetupTime = 3; /* 鍦板潃寤虹珛鏃堕棿(ADDSET)涓�3涓猣smc_ker_ck=6*3=18ns */
        fsmc_write_handle.DataSetupTime = 3;    /* 鏁版嵁淇濇寔鏃堕棿(DATAST)涓�3涓猣smc_ker_ck=6*3=18ns */
        FSMC_NORSRAM_Extended_Timing_Init(g_sram_handle.Extended, &fsmc_write_handle, g_sram_handle.Init.NSBank, g_sram_handle.Init.ExtendedMode);
    }
    else if (lcddev.id == 0x9806 || lcddev.id == 0x9341 || lcddev.id == 0x5510)
    {
        /* 閲嶆柊閰嶇疆鍐欐椂搴忔帶鍒跺瘎瀛樺櫒鐨勬椂搴� */
        fsmc_write_handle.AddressSetupTime = 2; /* 鍦板潃寤虹珛鏃堕棿(ADDSET)涓�2涓猣smc_ker_ck=6*2=12ns */
        fsmc_write_handle.DataSetupTime = 2;    /* 鏁版嵁淇濇寔鏃堕棿(DATAST)涓�2涓猣smc_ker_ck=6*2=12ns */
        FSMC_NORSRAM_Extended_Timing_Init(g_sram_handle.Extended, &fsmc_write_handle, g_sram_handle.Init.NSBank, g_sram_handle.Init.ExtendedMode);
    }
    else if (lcddev.id == 0x5310 || lcddev.id == 0x7796 || lcddev.id == 0x1963)
    {
        /* 閲嶆柊閰嶇疆鍐欐椂搴忔帶鍒跺瘎瀛樺櫒鐨勬椂搴� */
        fsmc_write_handle.AddressSetupTime = 1; /* 鍦板潃寤虹珛鏃堕棿(ADDSET)涓�1涓猣smc_ker_ck=6*1=6ns */
        fsmc_write_handle.DataSetupTime = 1;    /* 鏁版嵁淇濇寔鏃堕棿(DATAST)涓�1涓猣smc_ker_ck=6*1=6ns */
        FSMC_NORSRAM_Extended_Timing_Init(g_sram_handle.Extended, &fsmc_write_handle, g_sram_handle.Init.NSBank, g_sram_handle.Init.ExtendedMode);
    }

    lcd_display_dir(0); /* 榛樿涓虹珫灞� */
    LCD_BL(1);          /* 鐐逛寒鑳屽厜 */
    lcd_clear(WHITE);
}

/**
 * @brief       娓呭睆鍑芥暟
 * @param       color: 瑕佹竻灞忕殑棰滆壊
 * @retval      鏃�
 */
void lcd_clear(uint16_t color)
{
    uint32_t index = 0;
    uint32_t totalpoint = lcddev.width;

    totalpoint *= lcddev.height;    /* 寰楀埌鎬荤偣鏁� */
    lcd_set_cursor(0x00, 0x0000);   /* 璁剧疆鍏夋爣浣嶇疆 */
    lcd_write_ram_prepare();        /* 寮�濮嬪啓鍏RAM */

    for (index = 0; index < totalpoint; index++)
    {
        LCD->LCD_RAM = color;
    }
}

/**
 * @brief       鍦ㄦ寚瀹氬尯鍩熷唴濉厖鍗曚釜棰滆壊
 * @param       (sx,sy),(ex,ey):濉厖鐭╁舰瀵硅鍧愭爣,鍖哄煙澶у皬涓�:(ex - sx + 1) * (ey - sy + 1)
 * @param       color:  瑕佸～鍏呯殑棰滆壊(32浣嶉鑹�,鏂逛究鍏煎LTDC)
 * @retval      鏃�
 */
void lcd_fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t color)
{
    uint16_t i, j;
    uint16_t xlen = 0;
    xlen = ex - sx + 1;

    for (i = sy; i <= ey; i++)
    {
        lcd_set_cursor(sx, i);      /* 璁剧疆鍏夋爣浣嶇疆 */
        lcd_write_ram_prepare();    /* 寮�濮嬪啓鍏RAM */

        for (j = 0; j < xlen; j++)
        {
            LCD->LCD_RAM = color;   /* 鏄剧ず棰滆壊 */
        }
    }
}

/**
 * @brief       鍦ㄦ寚瀹氬尯鍩熷唴濉厖鎸囧畾棰滆壊鍧�
 * @param       (sx,sy),(ex,ey):濉厖鐭╁舰瀵硅鍧愭爣,鍖哄煙澶у皬涓�:(ex - sx + 1) * (ey - sy + 1)
 * @param       color: 瑕佸～鍏呯殑棰滆壊鏁扮粍棣栧湴鍧�
 * @retval      鏃�
 */
void lcd_color_fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *color)
{
    uint16_t height, width;
    uint16_t i, j;

    width = ex - sx + 1;            /* 寰楀埌濉厖鐨勫搴� */
    height = ey - sy + 1;           /* 楂樺害 */

    for (i = 0; i < height; i++)
    {
        lcd_set_cursor(sx, sy + i); /* 璁剧疆鍏夋爣浣嶇疆 */
        lcd_write_ram_prepare();    /* 寮�濮嬪啓鍏RAM */

        for (j = 0; j < width; j++)
        {
            LCD->LCD_RAM = color[i * width + j]; /* 鍐欏叆鏁版嵁 */
        }
    }
}

/**
 * @brief       鐢荤嚎
 * @param       x1,y1: 璧风偣鍧愭爣
 * @param       x2,y2: 缁堢偣鍧愭爣
 * @param       color: 绾跨殑棰滆壊
 * @retval      鏃�
 */
void lcd_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
{
    uint16_t t;
    int xerr = 0, yerr = 0, delta_x, delta_y, distance;
    int incx, incy, row, col;
    delta_x = x2 - x1;      /* 璁＄畻鍧愭爣澧為噺 */
    delta_y = y2 - y1;
    row = x1;
    col = y1;

    if (delta_x > 0)
    {
        incx = 1;       /* 璁剧疆鍗曟鏂瑰悜 */
    }
    else if (delta_x == 0)
    {
        incx = 0;       /* 鍨傜洿绾� */
    }
    else
    {
        incx = -1;
        delta_x = -delta_x;
    }

    if (delta_y > 0)
    {
        incy = 1;
    }
    else if (delta_y == 0)
    {
        incy = 0;       /* 姘村钩绾� */
    }
    else
    {
        incy = -1;
        delta_y = -delta_y;
    }

    if ( delta_x > delta_y)
    {
        distance = delta_x;  /* 閫夊彇鍩烘湰澧為噺鍧愭爣杞� */
    }
    else
    {
        distance = delta_y;
    }

    for (t = 0; t <= distance + 1; t++)     /* 鐢荤嚎杈撳嚭 */
    {
        lcd_draw_point(row, col, color);    /* 鐢荤偣 */
        xerr += delta_x;
        yerr += delta_y;

        if (xerr > distance)
        {
            xerr -= distance;
            row += incx;
        }

        if (yerr > distance)
        {
            yerr -= distance;
            col += incy;
        }
    }
}

/**
 * @brief       鐢绘按骞崇嚎
 * @param       x,y   : 璧风偣鍧愭爣
 * @param       len   : 绾块暱搴�
 * @param       color : 鐭╁舰鐨勯鑹�
 * @retval      鏃�
 */
void lcd_draw_hline(uint16_t x, uint16_t y, uint16_t len, uint16_t color)
{
    if ((len == 0) || (x > lcddev.width) || (y > lcddev.height))
    {
        return;
    }

    lcd_fill(x, y, x + len - 1, y, color);
}

/**
 * @brief       鐢荤煩褰�
 * @param       x1,y1: 璧风偣鍧愭爣
 * @param       x2,y2: 缁堢偣鍧愭爣
 * @param       color: 鐭╁舰鐨勯鑹�
 * @retval      鏃�
 */
void lcd_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
{
    lcd_draw_line(x1, y1, x2, y1, color);
    lcd_draw_line(x1, y1, x1, y2, color);
    lcd_draw_line(x1, y2, x2, y2, color);
    lcd_draw_line(x2, y1, x2, y2, color);
}

/**
 * @brief       鐢诲渾
 * @param       x0,y0 : 鍦嗕腑蹇冨潗鏍�
 * @param       r     : 鍗婂緞
 * @param       color : 鍦嗙殑棰滆壊
 * @retval      鏃�
 */
void lcd_draw_circle(uint16_t x0, uint16_t y0, uint8_t r, uint16_t color)
{
    int a, b;
    int di;

    a = 0;
    b = r;
    di = 3 - (r << 1);       /* 鍒ゆ柇涓嬩釜鐐逛綅缃殑鏍囧織 */

    while (a <= b)
    {
        lcd_draw_point(x0 + a, y0 - b, color);  /* 5 */
        lcd_draw_point(x0 + b, y0 - a, color);  /* 0 */
        lcd_draw_point(x0 + b, y0 + a, color);  /* 4 */
        lcd_draw_point(x0 + a, y0 + b, color);  /* 6 */
        lcd_draw_point(x0 - a, y0 + b, color);  /* 1 */
        lcd_draw_point(x0 - b, y0 + a, color);
        lcd_draw_point(x0 - a, y0 - b, color);  /* 2 */
        lcd_draw_point(x0 - b, y0 - a, color);  /* 7 */
        a++;

        /* 浣跨敤Bresenham绠楁硶鐢诲渾 */
        if (di < 0)
        {
            di += 4 * a + 6;
        }
        else
        {
            di += 10 + 4 * (a - b);
            b--;
        }
    }
}

/**
 * @brief       濉厖瀹炲績鍦�
 * @param       x,y  : 鍦嗕腑蹇冨潗鏍�
 * @param       r    : 鍗婂緞
 * @param       color: 鍦嗙殑棰滆壊
 * @retval      鏃�
 */
void lcd_fill_circle(uint16_t x, uint16_t y, uint16_t r, uint16_t color)
{
    uint32_t i;
    uint32_t imax = ((uint32_t)r * 707) / 1000 + 1;
    uint32_t sqmax = (uint32_t)r * (uint32_t)r + (uint32_t)r / 2;
    uint32_t xr = r;

    lcd_draw_hline(x - r, y, 2 * r, color);

    for (i = 1; i <= imax; i++)
    {
        if ((i * i + xr * xr) > sqmax)
        {
            /* draw lines from outside */
            if (xr > imax)
            {
                lcd_draw_hline (x - i + 1, y + xr, 2 * (i - 1), color);
                lcd_draw_hline (x - i + 1, y - xr, 2 * (i - 1), color);
            }

            xr--;
        }

        /* draw lines from inside (center) */
        lcd_draw_hline(x - xr, y + i, 2 * xr, color);
        lcd_draw_hline(x - xr, y - i, 2 * xr, color);
    }
}

/**
 * @brief       鍦ㄦ寚瀹氫綅缃樉绀轰竴涓瓧绗�
 * @param       x,y  : 鍧愭爣
 * @param       chr  : 瑕佹樉绀虹殑瀛楃:" "--->"~"
 * @param       size : 瀛椾綋澶у皬 12/16/24/32
 * @param       mode : 鍙犲姞鏂瑰紡(1); 闈炲彔鍔犳柟寮�(0);
 * @param       color : 瀛楃鐨勯鑹�;
 * @retval      鏃�
 */
void lcd_show_char(uint16_t x, uint16_t y, uint8_t chr, uint8_t size, uint8_t mode, uint16_t color)
{
    uint8_t temp, t1, t;
    uint16_t y0 = y;
    uint8_t csize = 0;
    uint8_t *pfont = 0;

    csize = (size / 8 + ((size % 8) ? 1 : 0)) * (size / 2); /* 寰楀埌瀛椾綋涓�涓瓧绗﹀搴旂偣闃甸泦鎵�鍗犵殑瀛楄妭鏁� */
    chr = chr - ' ';    /* 寰楀埌鍋忕Щ鍚庣殑鍊硷紙ASCII瀛楀簱鏄粠绌烘牸寮�濮嬪彇妯★紝鎵�浠�-' '灏辨槸瀵瑰簲瀛楃鐨勫瓧搴擄級 */

    switch (size)
    {
        case 12:
            pfont = (uint8_t *)asc2_1206[chr];  /* 璋冪敤1206瀛椾綋 */
            break;

        case 16:
            pfont = (uint8_t *)asc2_1608[chr];  /* 璋冪敤1608瀛椾綋 */
            break;

        case 24:
            pfont = (uint8_t *)asc2_2412[chr];  /* 璋冪敤2412瀛椾綋 */
            break;

        case 32:
            pfont = (uint8_t *)asc2_3216[chr];  /* 璋冪敤3216瀛椾綋 */
            break;

        default:
            return ;
    }

    for (t = 0; t < csize; t++)
    {
        temp = pfont[t];                            /* 鑾峰彇瀛楃鐨勭偣闃垫暟鎹� */

        for (t1 = 0; t1 < 8; t1++)                  /* 涓�涓瓧鑺�8涓偣 */
        {
            if (temp & 0x80)                        /* 鏈夋晥鐐�,闇�瑕佹樉绀� */
            {
                lcd_draw_point(x, y, color);        /* 鐢荤偣鍑烘潵,瑕佹樉绀鸿繖涓偣 */
            }
            else if (mode == 0)                     /* 鏃犳晥鐐�,涓嶆樉绀� */
            {
                lcd_draw_point(x, y, g_back_color); /* 鐢昏儗鏅壊,鐩稿綋浜庤繖涓偣涓嶆樉绀�(娉ㄦ剰鑳屾櫙鑹茬敱鍏ㄥ眬鍙橀噺鎺у埗) */
            }

            temp <<= 1;                             /* 绉讳綅, 浠ヤ究鑾峰彇涓嬩竴涓綅鐨勭姸鎬� */
            y++;

            if (y >= lcddev.height)return;          /* 瓒呭尯鍩熶簡 */

            if ((y - y0) == size)                   /* 鏄剧ず瀹屼竴鍒椾簡? */
            {
                y = y0; /* y鍧愭爣澶嶄綅 */
                x++;    /* x鍧愭爣閫掑 */

                if (x >= lcddev.width)
                {
                    return;       /* x鍧愭爣瓒呭尯鍩熶簡 */
                }

                break;
            }
        }
    }
}

/**
 * @brief       骞虫柟鍑芥暟, m^n
 * @param       m: 搴曟暟
 * @param       n: 鎸囨暟
 * @retval      m鐨刵娆℃柟
 */
static uint32_t lcd_pow(uint8_t m, uint8_t n)
{
    uint32_t result = 1;

    while (n--)
    {
        result *= m;
    }

    return result;
}

/**
 * @brief       鏄剧ずlen涓暟瀛�
 * @param       x,y : 璧峰鍧愭爣
 * @param       num : 鏁板��(0 ~ 2^32)
 * @param       len : 鏄剧ず鏁板瓧鐨勪綅鏁�
 * @param       size: 閫夋嫨瀛椾綋 12/16/24/32
 * @param       color : 鏁板瓧鐨勯鑹�;
 * @retval      鏃�
 */
void lcd_show_num(uint16_t x, uint16_t y, uint32_t num, uint8_t len, uint8_t size, uint16_t color)
{
    uint8_t t, temp;
    uint8_t enshow = 0;

    for (t = 0; t < len; t++)   /* 鎸夋�绘樉绀轰綅鏁板惊鐜� */
    {
        temp = (num / lcd_pow(10, len - t - 1)) % 10;   /* 鑾峰彇瀵瑰簲浣嶇殑鏁板瓧 */

        if (enshow == 0 && t < (len - 1))               /* 娌℃湁浣胯兘鏄剧ず,涓旇繕鏈変綅瑕佹樉绀� */
        {
            if (temp == 0)
            {
                lcd_show_char(x + (size / 2) * t, y, ' ', size, 0, color);  /* 鏄剧ず绌烘牸,鍗犱綅 */
                continue;       /* 缁х画涓嬩釜涓�浣� */
            }
            else
            {
                enshow = 1;     /* 浣胯兘鏄剧ず */
            }
        }

        lcd_show_char(x + (size / 2) * t, y, temp + '0', size, 0, color);   /* 鏄剧ず瀛楃 */
    }
}

/**
 * @brief       鎵╁睍鏄剧ずlen涓暟瀛�(楂樹綅鏄�0涔熸樉绀�)
 * @param       x,y : 璧峰鍧愭爣
 * @param       num : 鏁板��(0 ~ 2^32)
 * @param       len : 鏄剧ず鏁板瓧鐨勪綅鏁�
 * @param       size: 閫夋嫨瀛椾綋 12/16/24/32
 * @param       mode: 鏄剧ず妯″紡
 *              [7]:0,涓嶅～鍏�;1,濉厖0.
 *              [6:1]:淇濈暀
 *              [0]:0,闈炲彔鍔犳樉绀�;1,鍙犲姞鏄剧ず.
 * @param       color : 鏁板瓧鐨勯鑹�;
 * @retval      鏃�
 */
void lcd_show_xnum(uint16_t x, uint16_t y, uint32_t num, uint8_t len, uint8_t size, uint8_t mode, uint16_t color)
{
    uint8_t t, temp;
    uint8_t enshow = 0;

    for (t = 0; t < len; t++)       /* 鎸夋�绘樉绀轰綅鏁板惊鐜� */
    {
        temp = (num / lcd_pow(10, len - t - 1)) % 10;    /* 鑾峰彇瀵瑰簲浣嶇殑鏁板瓧 */

        if (enshow == 0 && t < (len - 1))   /* 娌℃湁浣胯兘鏄剧ず,涓旇繕鏈変綅瑕佹樉绀� */
        {
            if (temp == 0)
            {
                if (mode & 0x80)    /* 楂樹綅闇�瑕佸～鍏�0 */
                {
                    lcd_show_char(x + (size / 2) * t, y, '0', size, mode & 0x01, color);    /* 鐢�0鍗犱綅 */
                }
                else
                {
                    lcd_show_char(x + (size / 2) * t, y, ' ', size, mode & 0x01, color);    /* 鐢ㄧ┖鏍煎崰浣� */
                }

                continue;
            }
            else
            {
                enshow = 1;         /* 浣胯兘鏄剧ず */
            }

        }

        lcd_show_char(x + (size / 2) * t, y, temp + '0', size, mode & 0x01, color);
    }
}

/**
 * @brief       鏄剧ず瀛楃涓�
 * @param       x,y         : 璧峰鍧愭爣
 * @param       width,height: 鍖哄煙澶у皬
 * @param       size        : 閫夋嫨瀛椾綋 12/16/24/32
 * @param       p           : 瀛楃涓查鍦板潃
 * @param       color       : 瀛楃涓茬殑棰滆壊;
 * @retval      鏃�
 */
void lcd_show_string(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t size, char *p, uint16_t color)
{
    uint8_t x0 = x;
    
    width += x;
    height += y;

    while ((*p <= '~') && (*p >= ' '))   /* 鍒ゆ柇鏄笉鏄潪娉曞瓧绗�! */
    {
        if (x >= width)
        {
            x = x0;
            y += size;
        }

        if (y >= height)
        {
            break;      /* 閫�鍑� */
        }

        lcd_show_char(x, y, *p, size, 0, color);
        x += size / 2;
        p++;
    }
}

/**
 * @brief       鏄剧ず瀛楃涓�
 * @param       x,y         : 璧峰鍧愭爣
 * @param       size        : 閫夋嫨瀛椾綋 12/16/24/32
 * @param       p           : 瀛楃涓查鍦板潃
 * @retval      鏃�
 */
void lcd_show_str(uint16_t x, uint16_t y, uint8_t size, char *p, uint16_t color)
{
    uint8_t x0 = x;

    uint16_t width = x + size / 2 * strlen(p);
    uint16_t height = y + size;

    while ((*p <= '~') && (*p >= ' '))   /* 鍒ゆ柇鏄笉鏄潪娉曞瓧绗�! */
    {
        if (x >= width)
        {
            x = x0;
            y += size;
        }

        if (y >= height)
        {
            break;      /* 閫�鍑� */
        }

        lcd_show_char(x, y, *p, size, 0, color);
        x += size / 2;
        p++;
    }
}














